home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / zc / p2.c < prev    next >
C/C++ Source or Header  |  1989-03-08  |  14KB  |  843 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    p2.c
  12.  *
  13.  *    Expression tree routines.
  14.  *
  15.  *    Constant folding, typing of nodes, simple transformations.
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include "param.h"
  20. #include "tok.h"
  21. #include "nodes.h"
  22. #include "cookie.h"
  23.  
  24. #if MMCC
  25. overlay "pass2"
  26. #endif
  27.  
  28. extern int xflags[];
  29. #define debug xflags['t'-'a']
  30.  
  31. extern nmerrors;
  32. NODEP bas_type();
  33.  
  34. do_expr(np, cookie)
  35. NODE *np;
  36. {
  37.     if (np == NULL)
  38.         return;
  39. /*    include if want only one error at a time
  40.     if (nmerrors) {
  41.         freenode(np);
  42.         return;
  43.     }
  44. */
  45.     p2_expr(&np);
  46.     genx(np, cookie);
  47. }
  48.  
  49. p2_expr(npp)
  50. NODEP *npp;
  51. {
  52.     NODEP np = *npp;
  53.  
  54.     if (np == NULL) return;
  55.     if (debug > 1) {
  56.         printf("P2 enter");
  57.         printnode(np);
  58.     }
  59.     confold(npp,0);
  60.     np = *npp;
  61.     form_types(np);
  62.     if (debug) {
  63.         printf("p2_expr");
  64.         printnode(np);
  65.     }
  66.     return;
  67. }
  68.  
  69. form_types(np)
  70. NODEP np;
  71. {
  72.  
  73.     if (np == NULL) return;
  74.     switch (np->e_type) {
  75.     case E_SPEC:
  76.         switch (np->e_token) {    /* special cases */
  77.         case '.':
  78.         case ARROW:
  79.             form_types(np->n_left);
  80.             sel_type(np);
  81.             return;
  82.         case '(':
  83.             if (np->n_right) {
  84.                 form_types(np->n_right);    /* args */
  85.                 np->e_type = E_BIN;
  86.             } else
  87.                 np->e_type = E_UNARY;
  88.             fun_type(np);
  89.             return;
  90.         }
  91.         /* fall through */
  92.     case E_BIN:
  93.         form_types(np->n_left);
  94.         form_types(np->n_right);
  95.         b_types(np);
  96.         break;
  97.  
  98.     case E_UNARY:
  99.         form_types(np->n_left);
  100.         u_types(np);
  101.         break;
  102.  
  103.     case E_LEAF:
  104.         l_types(np);
  105.         break;
  106.     }
  107. }
  108.  
  109. /* (fun) (args) */
  110. fun_type(np)
  111. NODEP np;
  112. {
  113.     NODEP lp, typ;
  114.     NODEP allsyms(), new_fun();
  115.  
  116.     lp = np->n_left;
  117.     if (lp->e_token == ID) { /* may be new ID */
  118.         typ = allsyms(lp);
  119.         if (typ == NULL)
  120.             typ = new_fun(lp);
  121.         typ = typ->n_tptr;
  122.         lp->n_tptr = typ;
  123.         lp->n_flags |= N_COPYT;
  124.     } else {
  125.         form_types(lp);
  126.         typ = lp->n_tptr;
  127.     }
  128.     if (typ->t_token != '(') {    /* fun ret ? */
  129.         error("call non-fun");
  130.         goto bad;
  131.     }
  132.     typ = typ->n_tptr;
  133.     goto good;
  134. bad:
  135.     typ = bas_type(K_INT);
  136. good:
  137.     np->n_tptr = typ;
  138.     np->n_flags |= N_COPYT;
  139. }
  140.  
  141. /* (struct|union) (. or ->) ID */
  142. sel_type(xp)
  143. NODEP xp;
  144. {
  145.     NODEP np, sup;
  146.     int tok;
  147.     NODEP rv;
  148.     NODEP llook();
  149.  
  150.     np = xp->n_right;
  151.     sup = xp->n_left->n_tptr;
  152.     tok = xp->e_token;
  153.  
  154. /* already checked that np->e_token == ID */
  155.     if (tok == ARROW) {
  156.         if (sup->t_token != STAR) {
  157.             error("(non pointer)->");
  158.             goto bad;
  159.         }
  160.         sup = sup->n_tptr;
  161.     }
  162.     if (sup->t_token != K_STRUCT && sup->t_token != K_UNION) {
  163.         error("select non-struct");
  164.         goto bad;
  165.     }
  166.     rv = llook(sup->n_right, np);
  167.     if (rv == NULL) {
  168.         error("? member ID");
  169.         goto bad;
  170.     }
  171.     xp->e_offs = rv->e_offs;
  172.     if (rv->e_fldw) {
  173.         xp->e_fldw = rv->e_fldw;
  174.         xp->e_fldo = rv->e_fldo;
  175.     }
  176.     rv = rv->n_tptr;
  177.     goto good;
  178. bad:
  179.     rv = bas_type(K_INT);
  180. good:
  181.     xp->n_tptr = rv;
  182.     xp->n_flags |= N_COPYT;
  183.  
  184.     /* change to UNARY op */
  185.     xp->e_type = E_UNARY;
  186.     freenode(np);
  187.     xp->n_right = NULL;
  188.  
  189.     /* change ARY OF to PTR TO */
  190.     if (rv->t_token == '[')
  191.         see_array(xp);
  192. }
  193.  
  194. l_types(np)
  195. register NODE *np;
  196. {
  197.     NODEP allsyms();
  198.     register NODE *tp;
  199.  
  200.     switch (np->e_token) {
  201.     case ID:    /* already did see_id */
  202.         if (np->n_tptr->t_token == '[')    /* change to &ID */
  203.             see_array(np);
  204.         return;
  205.     case ICON:
  206.         tp = bas_type(icon_ty(np));
  207.         break;
  208.     case FCON:
  209.         tp = bas_type(K_DOUBLE);
  210.         break;
  211.     case SCON:
  212.         tp = bas_type(SCON);
  213.         break;
  214.     default:
  215.         errors("Weird leaf",np->n_name);
  216.     bad:
  217.         tp = bas_type(K_INT);
  218.     }
  219.     np->n_tptr = tp;
  220.     np->n_flags |= N_COPYT;
  221. }
  222.  
  223. u_types(np)
  224. NODEP np;
  225. {
  226.     NODEP tp;
  227.     NODEP lp = np->n_left;
  228.     NODEP normalty();
  229.  
  230.     tp = lp->n_tptr;    /* default */
  231.  
  232.     switch (np->e_token) {
  233.     case DOUBLE '+':
  234.     case DOUBLE '-':
  235.     case POSTINC:
  236.     case POSTDEC:
  237.         mustlval(lp);
  238.         mustty(lp, R_SCALAR);
  239.         if (tp->t_token == STAR)
  240.             np->e_offs = tp->n_tptr->t_size;
  241.         else
  242.             np->e_offs = 1;
  243.         break;
  244.     case STAR:
  245.         if (mustty(lp, R_POINTER)) goto bad;
  246.         tp = tp->n_tptr;
  247.         np->n_tptr = tp;
  248.         np->n_flags |= N_COPYT;
  249.  
  250.         /* Ary of to Ptr to */
  251.         if (tp->t_token == '[')
  252.             see_array(np);
  253.         return;
  254.     case UNARY '&':
  255.         mustlval(lp);
  256.         tp = allocnode();
  257.         tp->n_tptr = lp->n_tptr;
  258.         tp->n_flags |= N_COPYT;
  259.         tp->t_token = STAR;
  260.         sprintf(tp->n_name, "Ptr to");
  261.         tp->t_size = SIZE_P;
  262.         np->n_tptr = tp;
  263.         return;        /* no COPYT */
  264.     case UNARY '-':
  265.         mustty(lp, R_ARITH);
  266.         tp = normalty(lp, NULL);
  267.         break;
  268.     case TCONV:
  269.         mustty(lp, R_SCALAR);
  270.         if (np->n_tptr->t_token != K_VOID)
  271.             mustty(np, R_SCALAR);
  272.         return;        /* type already specified */
  273.     case '!':
  274.         mustty(lp, R_SCALAR);
  275.         tp = bas_type(K_INT);
  276.         break;
  277.     case '~':
  278.         mustty(lp, R_INTEGRAL);
  279.         tp = normalty(lp, NULL);
  280.         break;
  281.     default:
  282.         error("bad unary type");
  283.     bad:
  284.         tp = bas_type(K_INT);
  285.     }
  286.     np->n_tptr = tp;
  287.     np->n_flags |= N_COPYT;
  288. }
  289.  
  290. b_types(np)
  291. NODEP np;
  292. {
  293.     NODEP tp;
  294.     NODEP lp, rp;
  295.     NODEP normalty(), addty(), colonty();
  296.     int op;
  297.  
  298.     op = np->e_token;
  299.     if (isassign(op)) {
  300.         mustlval(np->n_left);
  301.         op -= (ASSIGN 0);
  302.     }
  303.  
  304.     lp = np->n_left;
  305.     rp = np->n_right;
  306.     tp = bas_type(K_INT);
  307.     switch (op) {
  308.     case '*':
  309.     case '/':
  310.         mustty(lp, R_ARITH);
  311.         mustty(rp, R_ARITH);
  312.         tp = normalty(lp,rp);
  313.         break;
  314.     case '%':
  315.     case '&':
  316.     case '|':
  317.     case '^':
  318.         mustty(lp, R_INTEGRAL);
  319.         mustty(rp, R_INTEGRAL);
  320.         tp = normalty(lp,rp);
  321.         break;
  322.     case '+':
  323.     case '-':
  324.         mustty(lp, R_SCALAR);
  325.         mustty(rp, R_SCALAR);
  326.         tp = addty(np);
  327.         break;
  328.     case DOUBLE '<':
  329.     case DOUBLE '>':
  330.         mustty(lp, R_INTEGRAL);
  331.         mustty(rp, R_INTEGRAL);
  332.         tp = normalty(lp, NULL);
  333.         break;
  334.     case '<':
  335.     case '>':
  336.     case LTEQ:
  337.     case GTEQ:
  338.     case DOUBLE '=':
  339.     case NOTEQ:
  340.         mustty(lp, R_SCALAR);
  341.         mustty(rp, R_SCALAR);
  342.         chkcmp(np);
  343.         break;        /* INT */
  344.     case DOUBLE '&':
  345.     case DOUBLE '|':
  346.         mustty(lp, R_SCALAR);
  347.         mustty(rp, R_SCALAR);
  348.         break;        /* INT */
  349.     case '?':
  350.         mustty(lp, R_SCALAR);
  351.         tp = rp->n_tptr;
  352.         break;
  353.     case ':':
  354.         if (same_type(lp->n_tptr, rp->n_tptr)) {
  355.             tp = lp->n_tptr;
  356.             break;
  357.         }
  358.         mustty(lp, R_SCALAR);
  359.         mustty(rp, R_SCALAR);
  360.         tp = colonty(np);
  361.         break;
  362.     case '=':
  363.         mustlval(lp);
  364.         mustty(lp, R_ASSN);
  365.         asn_chk(lp->n_tptr, rp);
  366.         tp = lp->n_tptr;
  367.         break;
  368.     case ',':
  369.         tp = rp->n_tptr;
  370.         break;
  371.     default:
  372.         error("bad binary type");
  373.     bad:
  374.         tp = bas_type(K_INT);
  375.     }
  376.     if (isassign(np->e_token)) {
  377.         /* ignore normal result -- result is left type */
  378.         tp = lp->n_tptr;
  379.     }
  380.     np->n_tptr = tp;
  381.     np->n_flags |= N_COPYT;
  382. }
  383.  
  384. long
  385. conlval(np)
  386. NODEP np;
  387. {
  388.     long i;
  389.  
  390.     confold(&np,0);
  391.     if (np->e_token == ICON) {
  392.         i = np->e_ival;
  393.         freenode(np);
  394.         return i;
  395.     }
  396.     error("need const expr");
  397.     return 0;
  398. }
  399.  
  400. conxval(np)
  401. NODEP np;
  402. {
  403.     return (int)conlval(np);
  404. }
  405.  
  406. confold(npp,spec)
  407. NODEP *npp;
  408. {
  409.     NODEP np;
  410.     NODEP tp, onp;
  411.     int tok,spl,spr;
  412.     long l;
  413.  
  414.     np = *npp;
  415.     if (np == NULL) return;
  416.     switch (np->e_type) {
  417.     case E_LEAF:
  418.             lcanon(np,spec);
  419.             return;
  420.     case E_UNARY:
  421.             confold(&np->n_left,0);
  422.             ucanon(np);
  423.             return;
  424.     case E_BIN:
  425.             confold(&np->n_left,0);
  426.             confold(&np->n_right,0);
  427.             if (np->e_token == '?') {
  428.                 tok = np->n_left->e_token;
  429.                 if (tok != ICON)
  430.                     return;
  431.                 l = np->n_left->e_ival;
  432.                 onp = np;
  433.                 tp = np->n_right;    /* ':' node */
  434.                 if (l) {    /* take true side */
  435.                     np = tp->n_left;
  436.                     tp->n_left = NULL;
  437.                 } else {    /* take false side */
  438.                     np = tp->n_right;
  439.                     tp->n_right = NULL;
  440.                 }
  441.                 freenode(onp);
  442.                 *npp = np;
  443.                 return;
  444.             }
  445.             bcanon(np);
  446.             if (np->e_flags & C_AND_A)
  447.                 b_assoc(np);
  448.             return;
  449.     case E_SPEC:
  450.         tok = np->e_token;
  451.         spl = spr = 0;
  452.         switch (tok) {
  453.         case '(':
  454.             spl = tok;    /* new name allowed */
  455.             break;
  456.         case '.':
  457.         case ARROW:
  458.             spr = tok;    /* look in struct sym.tab. */
  459.             break;
  460.         }
  461.         confold(&np->n_left,spl);
  462.         confold(&np->n_right,spr);
  463.         return;
  464.     }
  465. }
  466.  
  467. newicon(np,x,nf)
  468. NODE *np;
  469. long x;
  470. {
  471.     np->e_token = ICON;
  472.     np->e_ival = x;
  473.     np->e_flags = nf;
  474.     sprintf(np->n_name, "%ld", x);
  475.     np->e_type = E_LEAF;
  476.     if (np->n_left) {
  477.         freenode(np->n_left);
  478.         np->n_left = NULL;
  479.     }
  480.     if (np->n_right) {
  481.         freenode(np->n_right);
  482.         np->n_right = NULL;
  483.     }
  484. }
  485.  
  486. newfcon(np,x,nf)
  487. NODE *np;
  488. double x;
  489. {
  490.     np->e_token = FCON;
  491.     np->e_fval = x;
  492.     np->e_flags = nf;
  493.     sprintf(np->n_name, FLTFORM, x);
  494.     np->e_type = E_LEAF;
  495.     if (np->n_left) {
  496.         freenode(np->n_left);
  497.         np->n_left = NULL;
  498.     }
  499.     if (np->n_right) {
  500.         freenode(np->n_right);
  501.         np->n_right = NULL;
  502.     }
  503. }
  504.  
  505. /* LEAF */
  506. /* sptok is token if E_SPEC node is parent
  507.    and dont want to look at ID yet */
  508. lcanon(np,sptok)
  509. NODE *np;
  510. {
  511.     NODE *tp;
  512.     NODEP allsyms();
  513.     long x;
  514.  
  515.     if (np->e_token == ID) {
  516.         if (sptok)
  517.             return;
  518.         see_id(np);
  519.         return;
  520.     }
  521.     if (np->e_token == TSIZEOF) {
  522.         tp = np->n_tptr;
  523.         x = tp->t_size;
  524.         np->n_tptr = NULL;
  525.         if ((np->n_flags & N_COPYT) == 0)
  526.             freenode(tp);
  527.         newicon(np, x, 0);
  528.     }
  529. }
  530.  
  531. /* UNARY */
  532. ucanon(np)
  533. NODE *np;
  534. {
  535.     NODE *tp;
  536.     long x,l;
  537.     int lflags = 0;
  538.  
  539.     if (np->e_token == K_SIZEOF) {
  540.         tp = np->n_left;
  541.         confold(&tp,0);
  542.         form_types(tp);
  543.         tp = tp->n_tptr;
  544.         x = tp->t_size;
  545.         goto out;
  546.     }
  547.  
  548.     if (np->n_left->e_token == FCON) {
  549.         if (np->e_token == UNARY '-')
  550.             newfcon(np, -(np->n_left->e_fval));
  551.         return;
  552.     }
  553.     if (np->n_left->e_token != ICON)
  554.         return;
  555.     l = np->n_left->e_ival;
  556.     lflags = np->n_left->e_flags;
  557.     switch (np->e_token) {
  558.     case UNARY '-':
  559.             x = -l;        break;
  560.     case '~':
  561.             x = ~l;        break;
  562.     case '!':
  563.             x = !l;        break;
  564.     default:
  565.         return;
  566.     }
  567. out:
  568.     newicon(np, x, lflags);
  569. }
  570.  
  571. bcanon(np)
  572. register NODE *np;
  573. {
  574.     int ltok, rtok;
  575.     double l,r;
  576.     NODEP tp;
  577.  
  578.     ltok = np->n_left->e_token;
  579.     rtok = np->n_right->e_token;
  580.     if (ltok != ICON && ltok != FCON)
  581.         return;
  582.     if (rtok != ICON && rtok != FCON) {
  583.     /* left is ?CON, right is not */
  584.         if (np->e_flags & (C_AND_A|C_NOT_A)) {
  585.         /* reverse sides  - put CON on right */
  586.             tp = np->n_left;
  587.             np->n_left = np->n_right;
  588.             np->n_right = tp;
  589.             if (np->e_flags & C_NOT_A)
  590.                 swt_op(np);
  591.         }
  592.         return;
  593.     }
  594.     if (ltok == ICON && rtok == ICON) {
  595.         b2i(np);
  596.         return;
  597.     }
  598.     if (ltok == FCON)
  599.         l = np->n_left->e_fval;
  600.     else
  601.         l = (double)np->n_left->e_ival;
  602.     if (rtok == FCON)
  603.         r = np->n_right->e_fval;
  604.     else
  605.         r = (double)np->n_right->e_ival;
  606.     b2f(np,l,r);
  607. }
  608.  
  609. /* canon for assoc. & comm. op */
  610. /* this code will almost never be executed, but it was fun. */
  611. b_assoc(np)
  612. NODEP np;
  613. {
  614.     NODEP lp, rp;
  615.     int tok;
  616.  
  617.     lp = np->n_left;
  618.     if (lp->e_token != np->e_token)
  619.         return;
  620.     /* left is same op as np */
  621.     rp = np->n_right;
  622.     tok = lp->n_right->e_token;
  623.     if (tok != ICON && tok != FCON)
  624.         return;
  625.     /* left.right is ?CON */
  626.     tok = rp->e_token;
  627.     if (tok == ICON || tok == FCON) {
  628.         /* have 2 CONS l.r and r -- put together on r */
  629.         NODEP    ep;
  630.         ep = lp->n_left;
  631.         np->n_left = ep;
  632.         np->n_right = lp;
  633.         lp->n_left = rp;
  634.         /* can now fold 2 CONS */
  635.         bcanon(lp);
  636.     } else {
  637.         /* have 1 CON at l.r -- move to top right */
  638.         NODEP    kp;
  639.         kp = lp->n_right;
  640.         lp->n_right = rp;
  641.         np->n_right = kp;
  642.     }
  643. }
  644.  
  645. /* switch pseudo-commutative op */
  646. swt_op(np)
  647. NODEP np;
  648. {
  649.     int newtok;
  650.  
  651.     switch (np->e_token) {
  652.     case LTEQ:    newtok = '>';    break;
  653.     case GTEQ:    newtok = '<';    break;
  654.     case '<':    newtok = GTEQ;    break;
  655.     case '>':    newtok = LTEQ;    break;
  656.     default:
  657.         return;
  658.     }
  659.     np->e_token = newtok;
  660. }
  661.  
  662. /* BINARY 2 ICON's */
  663. b2i(np)
  664. register NODE *np;
  665. {
  666.     register long l,r,x;
  667.     int newflags,lflags;
  668.  
  669.     newflags = 0;
  670.  
  671.     r = np->n_right->e_ival;
  672.     newflags = np->n_right->e_flags;
  673.  
  674.     l = np->n_left->e_ival;
  675.     lflags = np->n_left->e_flags;
  676.     newflags = newflags>lflags ? newflags : lflags;
  677.  
  678.     switch (np->e_token) {
  679.     case '+':
  680.             x = l+r;    break;
  681.     case '-':
  682.             x = l-r;    break;
  683.     case '*':
  684.             x = l*r;    break;
  685.     case '/':
  686.             x = l/r;    break;
  687.     case '%':
  688.             x = l%r;    break;
  689.     case '>':
  690.             x = l>r;    break;
  691.     case '<':
  692.             x = l<r;    break;
  693.     case LTEQ:
  694.             x = l>=r;    break;
  695.     case GTEQ:
  696.             x = l<=r;    break;
  697.     case DOUBLE '=':
  698.             x = l==r;    break;
  699.     case NOTEQ:
  700.             x = l!=r;    break;
  701.     case '&':
  702.             x = l&r;    break;
  703.     case '|':
  704.             x = l|r;    break;
  705.     case '^':
  706.             x = l^r;    break;
  707.     case DOUBLE '<':
  708.             x = l<<r;    break;
  709.     case DOUBLE '>':
  710.             x = l>>r;    break;
  711.     default:
  712.         return;
  713.     }
  714.     newicon(np, x, newflags);
  715. }
  716.  
  717. /* BINARY 2 FCON's */
  718. b2f(np,l,r)
  719. register NODE *np;
  720. double l,r;
  721. {
  722.     register double x;
  723.     int ix, isint;
  724.  
  725.     isint = 0;
  726.  
  727.     switch (np->e_token) {
  728.     case '+':
  729.             x = l+r;    break;
  730.     case '-':
  731.             x = l-r;    break;
  732.     case '*':
  733.             x = l*r;    break;
  734.     case '/':
  735.             x = l/r;    break;
  736.     case '>':
  737.             ix = l>r;    isint++;    break;
  738.     case '<':
  739.             ix = l<r;    isint++;    break;
  740.     case LTEQ:
  741.             ix = l>=r;    isint++;    break;
  742.     case GTEQ:
  743.             ix = l<=r;    isint++;    break;
  744.     case DOUBLE '=':
  745.             ix = l==r;    isint++;    break;
  746.     case NOTEQ:
  747.             ix = l!=r;    isint++;    break;
  748.     default:
  749.         return;
  750.     }
  751.     if (isint)
  752.         newicon(np, (long)ix, 0);
  753.     else
  754.         newfcon(np, x);
  755. }
  756.  
  757. same_type(a,b)
  758. register NODE *a, *b;
  759. {
  760. more:
  761.     if (a == b)
  762.         return 1;
  763.     if (a == NULL || b == NULL)
  764.         return 0;
  765.     if (a->t_token != b->t_token)
  766.         return 0;
  767.     if (a->t_token != STAR && a->t_size != b->t_size)
  768.         return 0;
  769.     a = a->n_tptr;
  770.     b = b->n_tptr;
  771.     goto more;
  772. }
  773.  
  774. see_id(np)
  775. NODEP np;
  776. {
  777.     NODEP tp;
  778.     NODEP allsyms(), def_type();
  779.  
  780.     tp = allsyms(np);
  781.     if (tp == NULL) {
  782.         errorn("undefined:", np);
  783.         tp = def_type();
  784.         goto out;
  785.     }
  786.     switch (tp->e_sc) {
  787.     case ENUM_SC:
  788.         newicon(np, tp->e_ival, 0);
  789.         return;
  790.     case K_REGISTER:
  791.         np->e_rno = tp->e_rno;
  792.         /* fall through */
  793.     default:
  794.         np->e_sc = tp->e_sc;
  795.         np->e_offs = tp->e_offs;
  796.         tp = tp->n_tptr;
  797.     }
  798. out:
  799.     np->n_tptr = tp;
  800.     np->n_flags |= N_COPYT;
  801.  
  802.     /* special conversions */
  803.     if (tp->t_token == '(')
  804.         insptrto(np);
  805. }
  806.  
  807. insptrto(np)
  808. NODEP np;
  809. {
  810.     NODEP op, copyone();
  811.  
  812.     op = copyone(np);
  813.  
  814.     np->n_left = op;
  815.     np->e_token = UNARY '&';
  816.     np->e_type = E_UNARY;
  817.     strcpy(np->n_name, "&fun");
  818.     np->n_flags &= ~N_COPYT;
  819. }
  820.  
  821. /* np points to ID or STAR or '.' node
  822.     tptr is a COPY
  823.     tptr token is '[' */
  824.  
  825. see_array(np)
  826. NODEP np;
  827. {
  828.     NODEP tp, copyone();
  829.  
  830.     tp = copyone(np);
  831.     tp->n_left = np->n_left;
  832.     tp->n_tptr = tp->n_tptr->n_tptr;
  833.  
  834.     np->n_left = tp;
  835.     np->e_token = UNARY '&';
  836.     np->e_type = E_UNARY;
  837.     strcpy(np->n_name, "&ary");
  838.     arytoptr(np);
  839. /* leave old size
  840.     np->n_tptr->t_size = SIZE_P;
  841. */
  842. }
  843.